﻿using System.Collections.Generic;
using Cms.Application.Admin.Presenters;
using Cms.Application.Admin.Views;
using Cms.Domain;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace Cms.Tests.Unit.Application.Admin.Presenters
{
    [TestClass]
    public class AdminMenuPresenterTests : BasePresenterTests
    {
        private Administrator _admin;
        private Mock<IAdminMenuView> _viewMock;
        private AdminMenuPresenter _presenter;
        private Site _siteA;
        private Site _siteB;
        private Page _pageA1;
        private Page _pageA2;
        private Page _pageB1;
        private VisitedAdminUrl _adminVisit1;
        private VisitedAdminUrl _adminVisit2;
        private VisitedAdminUrl _adminVisit3;
        
        private void Prepare()
        {
            _admin = new Administrator();
            InitRepositoryFactoryMock();
            SystemRepositoryMock.Setup(m => m.GetCustomAdminPages(It.IsAny<int>())).Returns(new List<CustomAdminPage>());
            AdministratorRepositoryMock.Setup(m => m.GetAdministrator(1)).Returns(_admin);
            _viewMock = new Mock<IAdminMenuView>();
            _viewMock.SetupAllProperties();
            _viewMock.Setup(v => v.AdministratorID).Returns(1);
            // Setup two sites: siteA and siteB
            // siteA has two pages
            // siteB has one page
            // The flow goes like this: 
            // Visit 1 is pageA1 on siteA
            // Visit 2 is pageB1 on siteB
            // Visit 3 is pageA2 on siteA
            _siteA = new Site();
            _siteB = new Site();
            _pageA1 = new Page() { Site = _siteA };
            _pageA2 = new Page() { Site = _siteA };
            _pageB1 = new Page() { Site = _siteB };
            // Setup public visits
            VisitedPublicUrl publicUrl1 = new VisitedPublicUrl() { Administrator = _admin, Page = _pageA1 };
            VisitedPublicUrl publicUrl2 = new VisitedPublicUrl() { Administrator = _admin, Page = _pageB1 };
            VisitedPublicUrl publicUrl3 = new VisitedPublicUrl() { Administrator = _admin, Page = _pageA2 };
            _admin.VisitedPublicUrls.Add(publicUrl1);
            _admin.VisitedPublicUrls.Add(publicUrl2);
            _admin.VisitedPublicUrls.Add(publicUrl3);
            // Setup admin visits
            _adminVisit1 = new VisitedAdminUrl() { CurrentSite = _siteA };
            _adminVisit2 = new VisitedAdminUrl() { CurrentSite = _siteA };
            _adminVisit3 = new VisitedAdminUrl() { CurrentSite = _siteB };
            _admin.VisitedAdminUrls.Add(_adminVisit1);
            _admin.VisitedAdminUrls.Add(_adminVisit2);
            _admin.VisitedAdminUrls.Add(_adminVisit3);
            _presenter = new AdminMenuPresenter(_viewMock.Object, FactoryMock.Object);
        }

        [TestMethod]
        public void Initialize_ListPublicUrlsForSiteA_ShowVisit_3_and_1()
        {
            Prepare();
            _admin.CurrentSite = _siteA;
            _presenter.Initialize();
            _viewMock.Verify(m => m.SetLatestVisitedPublicUrls(It.Is<IList<VisitedPublicUrl>>(p => p.Count == 2)));
            _viewMock.Verify(m => m.SetLatestVisitedPublicUrls(It.Is<IList<VisitedPublicUrl>>(p => p[0].Page == _pageA2)));
            _viewMock.Verify(m => m.SetLatestVisitedPublicUrls(It.Is<IList<VisitedPublicUrl>>(p => p[1].Page == _pageA1)));
        }

        [TestMethod]
        public void Initialize_ListPublicUrlsForSiteB_ShowVisit_2()
        {
            Prepare();
            _admin.CurrentSite = _siteB;
            _presenter.Initialize();
            _viewMock.Verify(m => m.SetLatestVisitedPublicUrls(It.Is<IList<VisitedPublicUrl>>(p => p.Count == 1)));
            _viewMock.Verify(m => m.SetLatestVisitedPublicUrls(It.Is<IList<VisitedPublicUrl>>(p => p[0].Page == _pageB1)));
        }

        [TestMethod]
        public void Initialize_ListAdminUrlsForSiteA_ShowVisit_2_and_1()
        {
            Prepare();
            _admin.CurrentSite = _siteA;
            _presenter.Initialize();
            _viewMock.Verify(m => m.SetLatestVisitedAdminUrls(It.Is<IList<VisitedAdminUrl>>(p => p.Count == 2)));
            _viewMock.Verify(m => m.SetLatestVisitedAdminUrls(It.Is<IList<VisitedAdminUrl>>(p => p[0] == _adminVisit2)));
            _viewMock.Verify(m => m.SetLatestVisitedAdminUrls(It.Is<IList<VisitedAdminUrl>>(p => p[1] == _adminVisit1)));
        }

        [TestMethod]
        public void Initialize_ListAdminUrlsForSiteB_ShowVisit_3()
        {
            Prepare();
            _admin.CurrentSite = _siteB;
            _presenter.Initialize();
            _viewMock.Verify(m => m.SetLatestVisitedAdminUrls(It.Is<IList<VisitedAdminUrl>>(p => p.Count == 1)));
            _viewMock.Verify(m => m.SetLatestVisitedAdminUrls(It.Is<IList<VisitedAdminUrl>>(p => p[0] == _adminVisit3)));
        }
    }
}
